﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using System.Reflection;
using System.Timers;
using Ini;
using CommandHandler;

namespace Admin_Commands
{

    public class AdminCommands : MonoBehaviour
    {
        #region TOP: global variables are initialised here

        int updater3 = 0;
        public string lastUsedCommand = "無";

        public Timer itemsTimer;
        public Timer announceTimer;

        public int announceIndex = 0;
        public int itemsResetIntervalInSeconds = 2700;
        public int announceIntervalInSeconds = 600;
        public String[] AnnounceMessages;

        public List<String> WhitelistedSteamIDs = new List<string>();
        public bool usingWhitelist = false;
        public bool showWhiteListKickMessages = true;

        public bool usingGUI = true;
        public bool usePlayerHomes = false;
        public bool gift = false;

        public bool respawnVehicles = false;
        Dictionary<String, Vector3> frozenPlayers = new Dictionary<String, Vector3>();
        Dictionary<String, Vector3> vanishedPlayers = new Dictionary<String, Vector3>();        



        public String bigAssStringWithBannedPlayerNamesAndSteamIDs = "";   //empty until player issues /unban command

        Dictionary<String, Vector3> playerHomes =  new Dictionary<String, Vector3>();        
        BetterNetworkUser userToBeBanned;
        
        #endregion

        public void Start()
        {

            // --------------------------------------------------------------------------------------

            //Commands are being added here.
            //the 0's you see mean that these commands are usable by ALL players

            //a higher number means you need a higher permission rank to do said command
            // Individual player permission levels can be found in /mods/UserPermissionLevels.ini

            CommandList.add(new Command(0, Online, "online", "在線人數", "在线人数"));
            CommandList.add(new Command(0, Time, "time", "遊戲時間", "游戏时间"));
            CommandList.add(new Command(0, SetHome, "sethome", "設置紀錄點", "設置記錄點", "設置家", "设置纪录点", "设置记录点", "设置家"));
            CommandList.add(new Command(0, Home, "home", "回紀錄點", "回記錄點", "回家", "回纪录点", "回记录点"));
            CommandList.add(new Command(6, Announce, "repeat", "announce", "ann", "公告"));
            CommandList.add(new Command(8, Ban, "ban", "封禁"));
            CommandList.add(new Command(8, ReasonForBan, "reason", "r", "理由"));
            CommandList.add(new Command(7, ResetItems, "resetitems", "刷新物品"));
            CommandList.add(new Command(7, RepairVehicles, "repairvehicles", "修理車輛", "修理车辆"));
            CommandList.add(new Command(7, RefuelVehicles, "refuelvehicles", "車輛加油", "车辆加油"));
            CommandList.add(new Command(7, SirensOn, "sirens", "打開警笛", "打开警笛"));
            CommandList.add(new Command(7, SirensOff, "sirensoff", "關閉警笛", "关闭警笛"));
            CommandList.add(new Command(7, ResetZombies, "resetzombies", "刷新殭屍", "刷新僵尸"));
            CommandList.add(new Command(7, Killzombies, "killzombies", "殺死殭屍", "杀死僵尸"));
            CommandList.add(new Command(7, ReloadBans, "reloadbans", "讀取封禁名單", "读取封禁名单"));
            CommandList.add(new Command(7, SetItemsDelay, "setitemsdelay", "物品刷新時間", "物品刷新时间"));
            CommandList.add(new Command(7, SetAnnounceDelay, "setannouncedelay", "公告間隔時間", "公告间隔时间"));
            CommandList.add(new Command(8, EnableWhitelist, "enablewhitelist", "打開白名單", "打开白名单"));
            CommandList.add(new Command(8, DisableWhitelist, "disablewhitelist", "關閉白名單", "关闭白名单"));
            CommandList.add(new Command(6, Whitelist, "whitelist", "白名單", "白名单"));   //used for both /whitelist add & /whitelist remove
            CommandList.add(new Command(6, UnBan, "unban","解除封禁"));
            CommandList.add(new Command(6, TeleportToPlayer, "tp", "傳送", "传送"));
            CommandList.add(new Command(8, TeleportToMe, "tptome", "召喚", "召唤"));
            CommandList.add(new Command(6, TeleportToCoords, "tpto", "傳送座標", "传送座标"));
            CommandList.add(new Command(10, TeleportAll, "tpall", "召喚所有人", "召唤所有人"));
            CommandList.add(new Command(8, Kill, "kill", "殺死", "杀死"));
            CommandList.add(new Command(8, Heal, "heal", "補血", "补血"));
            CommandList.add(new Command(0, ShowAdminCommands, "commands", "指令表"));
            CommandList.add(new Command(6, TeleportCar, "car", "召喚車輛", "召唤车辆"));
            CommandList.add(new Command(8, SpawnItem, "i", "物品"));
            CommandList.add(new Command(8, SpawnKit, "kit", "大禮包", "大礼包"));
            CommandList.add(new Command(7, Kick, "kick", "踢除"));
            CommandList.add(new Command(8, GodMode, "god", "上帝模式"));
            CommandList.add(new Command(8, FreezePlayer, "freeze", "凍結", "冻结"));
            CommandList.add(new Command(8, UnFreezePlayer, "unfreeze", "解除凍結", "解除冻结"));
            CommandList.add(new Command(8, UnFreezeAll, "unfreezeall", "解除所有人"));
            CommandList.add(new Command(8, RespawnVehicles, "respawnvehicles", "刷新車輛", "刷新车辆"));
            CommandList.add(new Command(8, Vanish, "vanish", "隱形", "隐形"));
            CommandList.add(new Command(8, lag, "lag", "封鎖", "封锁"));
            CommandList.add(new Command(8, unlag, "unlag", "解除封鎖", "解除封锁"));
            CommandList.add(new Command(8, scarePlayer, "scare", "驚嚇", "惊吓"));
            CommandList.add(new Command(7, MaxSkills, "maxskills" ,"技能點", "技能点"));
            CommandList.add(new Command(0, Bambikit, "bambikit", "新手包", "gift"));
            CommandList.add(new Command(0, steam64ID, "id64", "64id", "查詢", "查询"));



            ReadConfigs();  //Read all the announcements, whitelist, player homes, ...

        }






        //Methods for each command :)

        #region Methods used for each of the commands above
        private void steam64ID(CommandArgs args)
        {

            String name = args.ParametersAsString;
            string steamid = "";

            steamid = UserList.getUserFromName(name).steamid;
            name = UserList.getUserFromName(name).name;
            Reference.Tell(args.sender.networkPlayer, "玩家" + name + "的steam64ID是" + steamid);


        }


        private void Bambikit(CommandArgs args)
        {
            if (gift)
            {
            int[] itemids = new int[] { 2002, 4017, 5017, 11, 8011, 13005, 0, 14031, 3002, 7006, 8008, 28000, 7004, 25001, 25001, 25001, 25001};
            Vector3 location = args.sender.position;

            foreach (int itemid in itemids)
                SpawnItems.spawnItem(itemid, 1, location);    
            }
            if (!gift)
            {
                Reference.Tell(args.sender.networkPlayer, "本伺服器未開啟新手包功能.");
            }
        }


        private void Online(CommandArgs args)
        {
            Reference.Tell(args.sender.networkPlayer, "現在有 " + UserList.NetworkUsers.Count + " 位玩家在線上");
        }


        private void Time(CommandArgs args)
        {
            NetworkChat.sendAlert("遊戲內時間: " + Sun.getTime());
        }

        
        private void SetHome(CommandArgs args)
        {
            if (usePlayerHomes)
            {
                Vector3 location = NetworkUserList.getModelFromPlayer(args.sender.networkPlayer).transform.position;
                setHome(args.sender.steamid, location);
                Reference.Tell(args.sender.networkPlayer, "記錄點設置完成.");
            }
            if (!usePlayerHomes)
            {
                Reference.Tell(args.sender.networkPlayer, "本伺服器未開啟紀錄點功能.");
            }
        }

        private void Home(CommandArgs args)
        {
            if (usePlayerHomes)
            {
                home(args.sender);
                Reference.Tell(args.sender.networkPlayer, "已傳送回紀錄點. 請五秒後再移動，以免被踢除");
            }
            if (!usePlayerHomes)
            {
                Reference.Tell(args.sender.networkPlayer, "本伺服器未開啟紀錄點功能.");
            }
        }

        private void Announce(CommandArgs args)
        {
            //Make all the parameters into 1 big string
            string concat = args.ParametersAsString;
            NetworkChat.sendAlert(concat);            
        }

        private void Ban(CommandArgs args)
        {
            String playerNameToBeBanned = args.ParametersAsString;
            String tempBanName;
            int number = 0;
            
            if (playerNameToBeBanned.Length < 3 && Int32.TryParse(name, out number))
            {
                userToBeBanned = UserList.users[number];
                tempBanName = userToBeBanned.name;
                Reference.Tell(args.sender.networkPlayer, "封禁 " + tempBanName + " 玩家的理由 ?  請再次輸入/reason <理由> 完成封禁");
            
            }
            else
            {
                userToBeBanned = UserList.getUserFromName(playerNameToBeBanned);
                tempBanName = userToBeBanned.name;
                Reference.Tell(args.sender.networkPlayer, "封禁 " + tempBanName + " 玩家的理由 ?  請再次輸入/reason <理由> 完成封禁");
            }
        }


        private void ReasonForBan(CommandArgs args)
        {
            String reason = args.ParametersAsString;
            if (args.Parameters.Count > 0)
                Ban(userToBeBanned, userToBeBanned.name + "被" + args.sender.name + "封禁，因為:" + reason);


            DateTime myDate = DateTime.Now;
            string myDateString = myDate.ToString("yyyy-MM-dd HH:mm:ss");

            System.IO.StreamWriter file = new StreamWriter("Unturned_Data/Managed/mods/AdminCommands/banlog.txt", true);
            file.WriteLine(myDate +": "+ args.sender.name + " Ban了:" + userToBeBanned.name + "(" + userToBeBanned.steamid + ")" + " 因為:" + reason);
            file.Close();
        }



        private void ResetItems(CommandArgs args)
        {
            SpawnItems.reset();
            NetworkChat.sendAlert(args.sender.name + " 已完成刷新所有物品");
        }

        private void RepairVehicles(CommandArgs args)
        {
            Vehicle[] vehicles = UnityEngine.Object.FindObjectsOfType(typeof(Vehicle)) as Vehicle[];
            foreach (Vehicle vehicle in vehicles)
            {
                vehicle.networkView.RPC("tellExploded", RPCMode.All, new object[] { false });
                vehicle.networkView.RPC("tellWrecked", RPCMode.All, new object[] { false });
                vehicle.heal(1000);
            }
            NetworkChat.sendAlert(args.sender.name + " 已完成修復 " + vehicles.Length + " 輛車");
        }

        private void RefuelVehicles(CommandArgs args)
        {
            Vehicle[] vehicles = UnityEngine.Object.FindObjectsOfType(typeof(Vehicle)) as Vehicle[];
            foreach (Vehicle vehicle in vehicles)
            {
                vehicle.fill(1000);
            }
            NetworkChat.sendAlert(args.sender.name + " 已完成加油 " + vehicles.Length + " 輛車");
        }

        private void SirensOn(CommandArgs args)
        {
            Vehicle[] vehicles = UnityEngine.Object.FindObjectsOfType(typeof(Vehicle)) as Vehicle[];
            foreach (Vehicle vehicle in vehicles)
            {
                vehicle.networkView.RPC("tellSirens", RPCMode.All, new object[] { true });
            }
        }

        private void SirensOff(CommandArgs args)
        {
            Vehicle[] vehicles = UnityEngine.Object.FindObjectsOfType(typeof(Vehicle)) as Vehicle[];
            foreach (Vehicle vehicle in vehicles)
            {
                vehicle.networkView.RPC("tellSirens", RPCMode.All, new object[] { false });
            }
        }

       private void ResetZombies(CommandArgs args)
        {
            SpawnAnimals.reset();
            NetworkChat.sendAlert(args.sender.name + " 已完成刷新殭屍 ");
        }

        private void Killzombies(CommandArgs args)
        {
            Zombie[] Zombies = UnityEngine.Object.FindObjectsOfType(typeof(Zombie)) as Zombie[];
            foreach (Zombie Zombie in Zombies)
            {
                Zombie.damage(500);
            }
            NetworkChat.sendAlert(args.sender.name + " 已經殺死 " + Zombies.Length + " 個殭屍");
        }


        private void ReloadBans(CommandArgs args)
        {
            NetworkBans.load();
        }

        private void SetItemsDelay(CommandArgs args)
        {
            String seconds = args.Parameters[0];
            setItemResetIntervalInSeconds(Convert.ToInt32(seconds));
        }

        private void SetAnnounceDelay(CommandArgs args)
        {
            String seconds = args.Parameters[0];
            setAnnounceIntervalInSeconds(Convert.ToInt32(seconds));
        }

        private void EnableWhitelist(CommandArgs args)
        {
            usingWhitelist = true;
            NetworkChat.sendAlert("白名單開啟.");
        }

        private void DisableWhitelist(CommandArgs args)
        {
            usingWhitelist = false;
            NetworkChat.sendAlert("白名單關閉.");
        }

        private void Whitelist(CommandArgs args)
        {
            if (args.Parameters[0].Equals("add") || args.Parameters[0].ToLower().Equals("添加"))
            {
                args.Parameters.RemoveAt(0);

                String name = args.ParametersAsString;
                string steamid = "";
                try
                {
                    steamid = UserList.getUserFromName(name).steamid;
                    name = UserList.getUserFromName(name).name;
                }
                catch
                {
                    if (name.StartsWith("765611"))
                    {
                        steamid = name;
                    }
                    else
                    {
                        Reference.Tell(args.sender.networkPlayer, "這位玩家不在線上，或者你輸入了錯誤的Steam64位ID");
                        return;
                    }

                }

                System.IO.StreamWriter file = new StreamWriter("Unturned_Data/Managed/mods/AdminCommands/UnturnedWhitelist.txt", true);
                file.WriteLine("");
                file.WriteLine(steamid);
                file.Close();
                WhitelistedSteamIDs.Add(steamid);

                Reference.Tell(args.sender.networkPlayer, "已添加 " + name + " (" + steamid + ") 到白名單");
            }
            else if (args.Parameters[0].ToLower().Equals("remove") || args.Parameters[0].ToLower().Equals("del") || args.Parameters[0].ToLower().Equals("rem") || args.Parameters[0].ToLower().Equals("移除"))
            {
                args.Parameters.RemoveAt(0);

                String name = args.ParametersAsString;
                string steamid = "";
                try
                {
                    steamid = UserList.getUserFromName(name).steamid;
                    name = UserList.getUserFromName(name).name;
                }
                catch
                {
                    if (name.StartsWith("765611"))
                    {
                        steamid = name;
                    }
                    else
                    {
                        Reference.Tell(args.sender.networkPlayer, "這位玩家不在線上，或者你輸入了錯誤的Steam64位ID");
                        return;
                    }

                }

                WhitelistedSteamIDs.Remove(steamid);

                File.Delete("Unturned_Data/Managed/mods/AdminCommands/UnturnedWhitelist.txt");
                System.IO.StreamWriter file = new StreamWriter("Unturned_Data/Managed/mods/AdminCommands/UnturnedWhitelist.txt", true);
                for (int i = 0; i < WhitelistedSteamIDs.Count; i++)
                {
                    file.WriteLine(WhitelistedSteamIDs[i]);
                }
                file.Close();

                Reference.Tell(args.sender.networkPlayer, "已移除 " + name + " (" + steamid + ") 從白名單");

            }
        }
        
        private void UnBan(CommandArgs args)
        {
            String name = args.ParametersAsString;
            if (unban(name))
            {
                Reference.Tell(args.sender.networkPlayer, name + " 已經從ban名單移除");
            }
            else 
            {
                  Reference.Tell(args.sender.networkPlayer, "在Ban名單中找不到 "+ name + "這位玩家");
            }
        }


        private void TeleportToPlayer(CommandArgs args)
        {
            String name = args.ParametersAsString;
            BetterNetworkUser user;
            int number = 0;

            if (name.Length < 3 && Int32.TryParse(name,out number))
            {
                user = UserList.users[number];
            }
            else
            {
                user = UserList.getUserFromName(name);
            }
            if (user != null)
            {
                teleportUserTo(args.sender, user.position, user.rotation);
            }

        }

        private void TeleportToMe(CommandArgs args)
        {
            String name = args.ParametersAsString;
            BetterNetworkUser user;
            int number = 0;

            if (name.Length < 3 && Int32.TryParse(name, out number))
            {
                user = UserList.users[number];
            }
            else
            {
                user = UserList.getUserFromName(name);
            }

            teleportUserTo(user, args.sender.position, args.sender.rotation);


        }

        private void TeleportToCoords(CommandArgs args)
        {
            float x = float.Parse(args.Parameters[0]);
            float y = float.Parse(args.Parameters[1]);
            float z = float.Parse(args.Parameters[2]);
            
            teleportUserTo(args.sender, new Vector3(x, y, z));

        }

        private void TeleportAll(CommandArgs args)
        {
            Vector3 location = args.sender.position;
            Quaternion rotation = args.sender.player.gameObject.transform.rotation;

            foreach (BetterNetworkUser user in UserList.users)
            {
                teleportUserTo(user, location, rotation);
            }
        }

        private void Kill(CommandArgs args)
        {
            String naam = args.ParametersAsString;
            UserList.getUserFromName(naam).player.gameObject.GetComponent<Life>().damage(500, "你被管理員殺死");
        }


        private void Heal(CommandArgs args)
        {
            if (args.Parameters.Count == 0)
                args.sender.player.gameObject.GetComponent<Life>().heal(100, true, true);
            else
            {
                String naam = args.ParametersAsString;
                UserList.getUserFromName(naam).player.gameObject.GetComponent<Life>().heal(100, true, true);
            }
        }

        private void Promote(CommandArgs args)
        {
            String naam = args.ParametersAsString;
            BetterNetworkUser user = UserList.getUserFromName(naam);

            UserList.promote(user.steamid);

            Reference.Tell(args.sender.networkPlayer, naam + " 被升級為管理員，權限等級:" + UserList.getPermission(user.steamid));
            Reference.Tell(user.networkPlayer, "你被升級為管理員，權限等級:" + UserList.getPermission(user.steamid));
        }
        
        private void ShowAdminCommands(CommandArgs args)
        {
            String string1 = " /ban, /kick, /repeat, /reason, /resetitems, /repairvehicles, /refuelvehicles";
            String string2 = " /resetzombies, /killzombies, /kill, /setitemsdelay, /enablewhitelist";
            String string3 = " /disablewhitelist, /whitelist add & remove, /unban, /reloadCommands, ";
            String string4 = " /tptome <playername>, /promote, /online, /heal, /tp, /tpto <x> <y> <z>";
            String string5 = " /i <itemid> <amount>, /car, /kit /sethome, /home  (if enabled)";

            Reference.Tell(args.sender.networkPlayer, string1);
            Reference.Tell(args.sender.networkPlayer, string2);
            Reference.Tell(args.sender.networkPlayer, string3);
            Reference.Tell(args.sender.networkPlayer, string4);
            Reference.Tell(args.sender.networkPlayer, string5);
        }

        private void TeleportCar(CommandArgs args)
        {
            Vector3 location = args.sender.position;
            Quaternion rotation = args.sender.rotation;
            Vector3 newPos = new Vector3(location[0] + 5, location[1] + 50, location[2]);

            if (args.Parameters.Count == 0) //Spawn random vehicle
            {                
                Vehicle[] mapVehicles = UnityEngine.Object.FindObjectsOfType(typeof(Vehicle)) as Vehicle[];

                int random = UnityEngine.Random.Range(0, mapVehicles.Length);
                Vehicle randomVehicle = mapVehicles[random];

                
                randomVehicle.transform.position = newPos;
            }

            else //create vehicle and destroy another one
            {
                String cartype = args.Parameters[0];
                if (!cartype.Contains("_")) {
                    cartype += "_0";
                }
                GameObject model = (GameObject)typeof(SpawnVehicles).GetFields()[0].GetValue(null);

                try
                {//destroy random car.. lol
                    if (model.transform.FindChild("models").childCount >= Loot.getCars() - 1)
                    {
                        int number = UnityEngine.Random.Range(0, Loot.getCars());
                        Transform child = model.transform.FindChild("models").GetChild(number);
                        Network.RemoveRPCs(child.networkView.viewID);
                        Network.Destroy(child.networkView.viewID);
                    } 
                }
                catch { }
                System.Threading.Timer timer;
                timer = new System.Threading.Timer(obj =>
                {
                    SpawnVehicles.create(cartype, 100, 100, newPos, rotation * Quaternion.Euler(-90f, 0f, 0f), new Color(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f)));
                    SpawnVehicles.save();
                }, null, 400, System.Threading.Timeout.Infinite);

                Reference.Tell(args.sender.networkPlayer, "已產生車輛 " + cartype);

            }
        }

        private void SpawnItem(CommandArgs args)
        {
            int itemid = Convert.ToInt32(args.Parameters[0]);
            int amount = 1;
            if (args.Parameters.Count == 2)
            {
                amount = Convert.ToInt32(args.Parameters[1]);
            }

            Vector3 location = args.sender.position;   

            for (int i = 0; i < amount; i++)
                SpawnItems.spawnItem(itemid, 1, location);

        }

        private void SpawnKit(CommandArgs args)
        {
            int[] itemids = new int[] { 0x7d4, 0x1b60, 0x2ee0, 0x232c, 0x2711, 0x2afb, 0x465e, 0x465e, 0x465e, 0x465e, 0x465e, 0x465e, 0x465e, 0xfb1, 0x1399, 11, 0x32c8, 0x32c8, 0x36c6, 0x36c6, 0x1f4f, 0x1f4d, 0xbba };
            Vector3 location = args.sender.position;

            foreach (int itemid in itemids)
                SpawnItems.spawnItem(itemid, 1, location);

        }

        private void Kick(CommandArgs args)
        {
            String name = args.ParametersAsString;
            Kick(name, name + "被" + args.sender.name + "踢出伺服器");
        }

        private void GodMode(CommandArgs args)
        {
            Life life = args.sender.player.gameObject.GetComponent<Life>();

            if (args.Parameters != null && args.Parameters.Count > 0 && args.ParametersAsString.ToLower().Equals("off"))
            {
                life.networkView.RPC("tellAllLife", RPCMode.All, new object[] { 100, 100, 100, 100, false, false });
                life.damage(1, "poke");
            }
            else
            {
                life.networkView.RPC("tellAllLife", RPCMode.All, new object[] { 10000, 100, 100, 100, false, false });
                life.damage(1, "poke");
            }

        }



        private void FreezePlayer(CommandArgs args)
        {
            string naam = args.ParametersAsString;
            BetterNetworkUser user = UserList.getUserFromName(naam);
            if (user != null)
            {
                Player player = user.player;
                frozenPlayers.Add(user.steamid, player.transform.position);
            }
            Reference.Tell(args.sender.networkPlayer, "已經凍結了" + user.name);

        }

        private void UnFreezePlayer(CommandArgs args)
        {
            string naam = args.ParametersAsString;
            BetterNetworkUser user = UserList.getUserFromName(naam);
            if (user != null)
            {
                frozenPlayers.Remove(user.steamid);
            }
            Reference.Tell(args.sender.networkPlayer, "解除凍結 " + user.name);
        }

        private void UnFreezeAll(CommandArgs args)
        {
            frozenPlayers.Clear();
            Reference.Tell(args.sender.networkPlayer, "解除凍結所有玩家 ");
        }

        private void RespawnVehicles(CommandArgs args)
        {            
            GameObject model = (GameObject)typeof(SpawnVehicles).GetFields()[0].GetValue(null);

            try   //Destroy all cars
            {
                Vehicle[] vehicles = UnityEngine.Object.FindObjectsOfType(typeof(Vehicle)) as Vehicle[];
                foreach (Vehicle vehicle in vehicles)
                {
                    vehicle.networkView.RPC("tellExploded", RPCMode.All, new object[] { true });
                    vehicle.networkView.RPC("tellWrecked", RPCMode.All, new object[] { true });
                }


                int amount = model.transform.FindChild("models").childCount;
                for (int i = 0; i< amount; i++)
                {
                    Transform child = model.transform.FindChild("models").GetChild(i);
                    Network.RemoveRPCs(child.networkView.viewID);
                    Network.Destroy(child.networkView.viewID);
                }
            }
            catch { }

            SpawnVehicles.save();
            Reference.Tell(args.sender.networkPlayer, "已移除車輛 "  + Loot.getCars() + " 車輛將在三秒後重新產生...");

            
            System.Threading.Timer timer;
            timer = new System.Threading.Timer(obj =>
            {
                respawnVehicles = true;
            }, null, 3000, System.Threading.Timeout.Infinite);
            
        }



        private void Vanish(CommandArgs args)
        {
            try
            {
                vanishedPlayers.Add(args.sender.steamid, new Vector3(0, 0, 0));
                Reference.Tell(args.sender.networkPlayer, "啟用隱形功能");
            }
            catch
            {
                vanishedPlayers.Remove(args.sender.steamid);
                Reference.Tell(args.sender.networkPlayer, "關閉隱形功能");
            }
        }


        private void lag(CommandArgs args)
        {
            string naam = args.ParametersAsString;
            BetterNetworkUser user = UserList.getUserFromName(naam);

            Network.SetReceivingEnabled(user.networkPlayer, 0, false);
            Reference.Tell(args.sender.networkPlayer, user.name + "已經被你封鎖網路封包" );
        }

        private void unlag(CommandArgs args)
        {
            string naam = args.ParametersAsString;
            BetterNetworkUser user = UserList.getUserFromName(naam);

            Network.SetReceivingEnabled(user.networkPlayer, 0, true);
            Reference.Tell(args.sender.networkPlayer, user.name + "已經解除封鎖網路封包");
        }


        private void scarePlayer(CommandArgs args)
        {
            string naam = args.ParametersAsString;
            BetterNetworkUser user = UserList.getUserFromName(naam);
            Vector3 location = user.position;

            for (int i = 0; i < 100; i++)
            {
                NetworkSounds.askSound("Sounds/Vehicles/horn", location, 50f, 1F, 20f);
            }

        }


        void MaxSkills(CommandArgs args)
        {
            args.sender.player.GetComponent<Skills>().learn(10000);
            //args.sender.player.GetComponent<Inventory>().addItem(new ServerItem(17000, 1, ItemState.getState(17000), args.sender.position));
            //throw new NotImplementedException();
            //Reference.Tell(args.sender.networkPlayer, "You have gained 10000 Experience!");

        }

        #endregion
        


















        
        // HELPER METHODS :D

        #region Helper Methods:  Used by the main command methods above to handle some stuff...



        private void teleportUserTo(BetterNetworkUser user, Vector3 target)
        {
            user.position = target;
            user.player.gameObject.GetComponent<Life>().networkView.RPC("tellStatePosition", RPCMode.All, new object[] { target, user.rotation });
            user.player.gameObject.GetComponent<NetworkInterpolation>().tellStatePosition_Pizza(target, user.rotation);

            Network.SetReceivingEnabled(user.networkPlayer, 0, false);

            System.Threading.Timer timer;
            timer = new System.Threading.Timer(obj =>
            {
                Network.SetReceivingEnabled(user.networkPlayer, 0, true);
            }, null, 2000, System.Threading.Timeout.Infinite);
        }

        private void teleportUserTo(BetterNetworkUser user, Vector3 targetposition, Quaternion targetrotation)
        {
            user.position = targetposition;
            user.player.gameObject.GetComponent<Life>().networkView.RPC("tellStatePosition", RPCMode.All, new object[] { targetposition, targetrotation });
            user.player.gameObject.GetComponent<NetworkInterpolation>().tellStatePosition_Pizza(targetposition, targetrotation);

            Network.SetReceivingEnabled(user.networkPlayer, 0, false);

            System.Threading.Timer timer;
            timer = new System.Threading.Timer(obj =>
            {
                Network.SetReceivingEnabled(user.networkPlayer, 0, true);
            }, null, 2000, System.Threading.Timeout.Infinite);
        }

        private void Ban(BetterNetworkUser userToBeBanned, string reason)
        {
            NetworkTools.ban(userToBeBanned.networkPlayer, userToBeBanned.name, userToBeBanned.steamid, reason);
        }

        public void announcesTimeElapsed(object sender, ElapsedEventArgs e)
        {
            announceNext();
        }


        private void announceNext()
        {
            for (int i = announceIndex; i < AnnounceMessages.Length; i++)
            {
                string message = AnnounceMessages[i];
                if (message.Equals(":"))
                {
                    announceIndex = i + 1;
                    return;
                }
                else
                {
                    NetworkChat.sendAlert(message);
                }
            }
            announceIndex = 0;
        }

        public void setAnnounceIntervalInSeconds(int seconds)
        {
            announceIntervalInSeconds = seconds;
            announceTimer.Stop();
            announceTimer.Interval = seconds * 1000;
            announceTimer.Start();
        }

        private void itemsTimeElapsed(object sender, ElapsedEventArgs e)
        {
            resetItems();
        }

        public void setItemResetIntervalInSeconds(int seconds)
        {
            itemsResetIntervalInSeconds = seconds;
            itemsTimer.Stop();
            itemsTimer.Interval = seconds * 1000;
            itemsTimer.Start();
        }

        public void resetItems()
        {
            SpawnItems.reset();
        }



        private static System.Random random = new System.Random((int)DateTime.Now.Ticks);//thanks to McAden
        private string RandomString(int size)
        {
            StringBuilder builder = new StringBuilder();
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }

            return builder.ToString();
        }


        
        private void Log(string p)
        {
            System.IO.StreamWriter file = new StreamWriter("Unturned_Data/Managed/mods/AdminCommands_Log.txt", true);
            file.WriteLine(p);

            file.Close();
        }
        

        private void kickNonWhitelistedPlayers()
        {
            if (usingWhitelist && updater3 <= 1)
            {
                foreach (BetterNetworkUser user in UserList.users)
                {
                    if (user.networkPlayer != Network.player && !WhitelistedSteamIDs.Contains(user.steamid))
                    {
                        if (showWhiteListKickMessages) {
                            Kick(user.name, user.name + " 請聯絡管理員申請白名單!");
                        }
                        else
                        {
                            NetworkChat.sendNotification(user.networkPlayer, user.name + " 請聯絡管理員申請白名單!");
                            Network.CloseConnection(user.networkPlayer, true);
                        }

                    }
                }
                this.updater3 = 100;
            }
            updater3--;
        }

        public void loadBans()
        {
            bigAssStringWithBannedPlayerNamesAndSteamIDs = PlayerPrefs.GetString("bans");
        }


        public void saveBans()
        {
            PlayerPrefs.SetString("bans", bigAssStringWithBannedPlayerNamesAndSteamIDs);
        }

        public bool unban(String name)
        {
            loadBans();
            string bannedppl = bigAssStringWithBannedPlayerNamesAndSteamIDs;

            if (bannedppl.Contains(name))
            {
                int startIndex = bannedppl.IndexOf(name);



                int length = name.Length + 1 + 17 + 2;

                String temp1 = bannedppl.Substring(0, startIndex);
                String temp2 = bannedppl.Substring(startIndex + length);
                bannedppl = temp1 + temp2;
            }

            else
            {
                return false;
            }

            bigAssStringWithBannedPlayerNamesAndSteamIDs = bannedppl;
            saveBans();
            NetworkBans.load();
            return true;
        }



        void Kick(String name, String reason)
        {
            BetterNetworkUser user = UserList.getUserFromName(name);
            NetworkTools.kick(user.networkPlayer, reason);
        }



        private void setHome(string steamID, Vector3 location)
        {
            if (playerHomes.ContainsKey(steamID))
            {
                string[] lines = System.IO.File.ReadAllLines(@"Unturned_Data/Managed/mods/AdminCommands/PlayerHomes.txt");
                File.Delete("Unturned_Data/Managed/mods/AdminCommands/PlayerHomes.txt");

                System.IO.StreamWriter file = new StreamWriter("Unturned_Data/Managed/mods/AdminCommands/PlayerHomes.txt", true);


                for (int i = 0; i < lines.Length; i++)
                {
                    if (!lines[i].StartsWith(steamID))
                    {
                        file.WriteLine(lines[i]);
                    }

                }
                file.Close();
            }
            System.IO.StreamWriter file2 = new StreamWriter("Unturned_Data/Managed/mods/AdminCommands/PlayerHomes.txt", true);
            file2.WriteLine(steamID + ":" + location.x + "," + location.y + "," + location.z);
            file2.Close();
            playerHomes[steamID] = location;
        }

        private void home(BetterNetworkUser user)
        {
            teleportUserTo(user, playerHomes[user.steamid]);
        }

        #endregion

        
        
        
        public void Update()
        {
            kickNonWhitelistedPlayers();

            if (respawnVehicles)
            {
                respawnVehicles = false;
                SpawnVehicles spawnveh = UnityEngine.Object.FindObjectOfType<SpawnVehicles>();
                spawnveh.onReady();
            }
            if (frozenPlayers.Count > 0)
            {
                foreach (KeyValuePair<String, Vector3> entry in frozenPlayers)
                {
                    BetterNetworkUser user = UserList.getUserFromSteamID(entry.Key);
                    if (user != null)
                    {
                        user.player.transform.position = entry.Value;

                        user.player.networkView.RPC("tellStatePosition", user.player.networkView.owner, new object[] { entry.Value, user.player.transform.rotation });
                    }
                    
                }
            }
            if (vanishedPlayers.Count > 0)
            {
                foreach (KeyValuePair<String, Vector3> entry in vanishedPlayers)
                {
                    BetterNetworkUser user = UserList.getUserFromSteamID(entry.Key);
                    if (user != null)
                    {
                        foreach (NetworkPlayer networkplayer in Network.connections)
                        {
                            if (Network.player != networkplayer && networkplayer != user.networkPlayer)
                            {
                                user.player.networkView.RPC("tellStatePosition", networkplayer, new object[] { new Vector3(0,0,0), user.rotation });

                            }
                        }

                    }

                }
            }
        }
     


        public void OnGUI()
        {
            if (usingGUI)
            {
                GUI.BeginGroup(new Rect(50, 100, 600, 70));
                GUI.Box(new Rect(0, 0, 530, 400), "管理員插件啟用中 中文化By Minidoracat 上次控制台輸入的指令為: " + CommandList.lastUsedCommand);
                GUI.EndGroup();
            }
        }

        #region Readconfig: Reads in all the configs at the start

        private void ReadConfigs()
        {
            Directory.CreateDirectory("Unturned_Data/Managed/mods/AdminCommands");


            if (!File.Exists("Unturned_Data/Managed/mods/AdminCommands/config.ini"))  //create config file
            {
                IniFile tempIni = new IniFile("Unturned_Data/Managed/mods/AdminCommands/config.ini");

                tempIni.IniWriteValue("Config", "Using Whitelist", "false");
                tempIni.IniWriteValue("Config", "Using Player Homes", "false");
                tempIni.IniWriteValue("Config", "Show gui", "true");
                tempIni.IniWriteValue("Config", "Show whitelist kick messages", "true");
                tempIni.IniWriteValue("Config", "gift", "false");

                tempIni.IniWriteValue("Security", "Using_console", "true");
                tempIni.IniWriteValue("Security", "Console_password", RandomString(8));
                tempIni.IniWriteValue("Security", "Require_command_confirmation", "false");

                tempIni.IniWriteValue("Timers", "Time between item respawns in seconds", "2700");
                tempIni.IniWriteValue("Timers", "Time between announces in seconds", "600");
            }

            IniFile ini = new IniFile("Unturned_Data/Managed/mods/AdminCommands/config.ini");

            //things that need to be added to existing files
            if (ini.IniReadValue("Config", "Show whitelist kick messages").Equals(""))
            {
                ini.IniWriteValue("Config", "Show whitelist kick messages", "true");
            }
            if (ini.IniReadValue("Security", "Using_console").Equals(""))
            {
                ini.IniWriteValue("Security", "Using_console", "true");
            }
            if (ini.IniReadValue("Security", "Console_password").Equals(""))
            {
                ini.IniWriteValue("Security", "Console_password", RandomString(8));
            }
            if (ini.IniReadValue("Security", "Require_command_confirmation").Equals(""))
            {
                ini.IniWriteValue("Security", "Require_command_confirmation", "false");
            }


            usingWhitelist = Boolean.Parse(ini.IniReadValue("Config", "Using Whitelist"));
            usingGUI = Boolean.Parse(ini.IniReadValue("Config", "Show gui"));
            usePlayerHomes = Boolean.Parse(ini.IniReadValue("Config", "Using Player Homes"));
            gift = Boolean.Parse(ini.IniReadValue("Config", "gift"));
            showWhiteListKickMessages = Boolean.Parse(ini.IniReadValue("Config", "Show whitelist kick messages"));

            itemsResetIntervalInSeconds = Int32.Parse(ini.IniReadValue("Timers", "Time between item respawns in seconds"));
            announceIntervalInSeconds = Int32.Parse(ini.IniReadValue("Timers", "Time between announces in seconds"));


            
            //WHITELIST
            if (!File.Exists("Unturned_Data/Managed/mods/AdminCommands/UnturnedWhitelist.txt"))  //create a template for whitelist
            {
                System.IO.StreamWriter file = new StreamWriter("Unturned_Data/Managed/mods/AdminCommands/UnturnedWhitelist.txt", true);
                file.WriteLine("76561197976976379");
                file.Close();
            }

            string[] whitelistedLines = System.IO.File.ReadAllLines(@"Unturned_Data/Managed/mods/AdminCommands/UnturnedWhitelist.txt");

            for (int i = 0; i < whitelistedLines.Length; i++)
            {
                if (whitelistedLines[i].Length > 10)
                {
                    WhitelistedSteamIDs.Add(whitelistedLines[i]);
                }
            }

            //PLAYER HOMES
            if (!File.Exists("Unturned_Data/Managed/mods/AdminCommands/playerHomes.txt"))  //create a template for playerHomes
            {
                System.IO.StreamWriter file = new StreamWriter("Unturned_Data/Managed/mods/AdminCommands/playerHomes.txt", true);
                file.WriteLine("");
                file.Close();
            }
            //BAN LOG
            if (!File.Exists("Unturned_Data/Managed/mods/AdminCommands/banlog.txt"))  //create a template for playerHomes
            {
                System.IO.StreamWriter file = new StreamWriter("Unturned_Data/Managed/mods/AdminCommands/Banlog.txt", true);
                file.WriteLine("");
                file.Close();
            }

            string[] tempHomes = System.IO.File.ReadAllLines(@"Unturned_Data/Managed/mods/AdminCommands/playerHomes.txt");
            for (int i = 0; i < tempHomes.Length; i++)
            {
                if (tempHomes[i].Length > 5)
                {
                    String id = tempHomes[i].Split(':')[0];
                    String location = tempHomes[i].Split(':')[1];

                    String x = location.Split(',')[0];
                    String y = location.Split(',')[1];
                    String z = location.Split(',')[2];

                    Vector3 loc = new Vector3(Convert.ToSingle(x), Convert.ToSingle(y), Convert.ToSingle(z));

                    playerHomes[id] = loc;
                }

            }

            //ANNOUNCEMENTS
            if (!File.Exists("Unturned_Data/Managed/mods/AdminCommands/UnturnedAnnounces.txt"))  //create a template for announcements
            {
                System.IO.StreamWriter file = new StreamWriter("Unturned_Data/Managed/mods/AdminCommands/UnturnedAnnounces.txt", true);
                file.WriteLine("This line will be announced 10 minutes after injecting (or whatever you change the interval to)");
                file.WriteLine("This line will be announced at the same time");
                file.WriteLine(":");
                file.WriteLine("This line will be announced 20 minutes after injecting  (2x interval)");
                file.WriteLine(":");
                file.WriteLine(":");
                file.WriteLine("This line will be announced 40 minutes after injecting  (4x interval)");
                file.WriteLine("And so forth.. then it will go back to the 1st line      (4x interval)");
                file.Close();
            }
            string[] announces = System.IO.File.ReadAllLines(@"Unturned_Data/Managed/mods/AdminCommands/UnturnedAnnounces.txt");
            AnnounceMessages = new String[announces.Length];
            for (int i = 0; i < announces.Length; i++)
            {
                AnnounceMessages[i] = announces[i];
            }


            itemsTimer = new Timer(itemsResetIntervalInSeconds * 1000);
            itemsTimer.Elapsed += new ElapsedEventHandler(this.itemsTimeElapsed);
            itemsTimer.Enabled = true;

            announceTimer = new Timer(announceIntervalInSeconds * 1000);
            announceTimer.Elapsed += new ElapsedEventHandler(this.announcesTimeElapsed);
            announceTimer.Enabled = true;

        }

        #endregion

    }

}